<?php
class paper
{
	// database
	protected $db;

	// account wrapper
	protected $wr;

	public function __construct()
	{
		$this->db=Zend_Registry::get('database');

		$this->wr=new wrapper('PId|Title|Author|Journal|Date|Keyword|'.
					'Abstract|Foundation|Reference|Search|Download',
				array('PId'=>'/[0-9]+/',
					'Title'=>'/.{4,}/',
					'Author'=>'/.+/',
					'Journal'=>'/.+/'),
				'PId');
	}

	// 过滤掉不再表中的参数
	public function filter($data)
	{
		return $this->wr->filter($data);
	}

	// 出错字段
	public function err_field()
	{
		return $this->wr->field;
	}

	// 检测参数
	function check($param)
	{
		return $this->wr->check($param);
	}

	// 检测论文名是否已经存在
	function check_title($title)
	{
		try {
			$result=$this->db->query('select PId from paper
					where Title=:title', array('title'=>$title));
			$row=$result->fetchAll();
			return count($row)==0;
		}
		catch (Zend_Excetpion $e) {
			return false;
		}
	}

	// 字符串to作者数组，格式：array(AId => 'Name', ...)
	// $s 必须以、或;号分隔。$s中所有格式为：Name(id=n)的名字将会被
	// 提取出来成为数组中 AId=>'Name'，元素，然后数组将被重新整理，
	// 去掉所有(id=n)，形成可输出的字符串。
	static function str_to_author(&$s)
	{
		$name=split('(、|，|;|,)', $s);
		$a=array();
		$s='';
		$sep='';
		foreach ($name as $d) {
			if (strlen($d)<1)
				continue;
			preg_match('/(.+)\(id=([0-9]+)\)$/', $d, $tmp);
			if (count($tmp)==3) { // 含有id项
				$s.=$sep.$d;
				$id=$tmp[2];
				$a[$id]=$tmp[1];
			}
			else
				$s.=$sep.$d;
			$sep=';';
		}
		return $a;
	}

	// 增加论文，成功返回插入的PId，失败返回-1
	function add($param)
	{
		$field=$this->wr->field_string($param);
		$key=$this->wr->field_string($param, '', ':');
		$value=$this->wr->filter($param);
		$author=self::str_to_author($value['Author']);
		$value['Date']=strtotime($value['Date']);
		// $value=self::escape($value);

		$result=$this->db->query("insert into paper ($field) 
				values($key)", $value);
		if ($result->rowCount()!=1)
			return -1;
		
		$pid=$this->db->lastInsertId();
		foreach ($author as $aid => $d) {
			$this->db->query('insert into author_paper(AId, PId)
					values(:aid, :pid)', 
				array('aid'=>$aid, 'pid'=>$pid));
		}

		return $pid;
	}

	// 查询出论文信息。如果aid=0则查询出所有人的论文。order为排序子句。
	// limit为查询出的条数，offset为开始查询的位置。
	function find($aid, $order='`Date` desc', $limit=10, $offset=0)
	{
		if (empty($aid))
			$where=' 1=1 ';
		else
			$where=' AId='.intval($aid).' and author_paper.PId=paper.PId ';
		$result=$this->db->query("select distinct paper.* 
				from paper, author_paper
				where $where order by $order limit $offset, $limit");
		return $result->fetchAll(Zend_Db::FETCH_ASSOC);
	}

	// 预处理字段，以便输出。
	static function pretreat($data)
	{
		$d=$data;
		foreach ($data as $k => $v) {
			switch ($k) {
			case 'Date':
				$d['Date']=date('Y(n)', $v);
				break;
			case 'Author':
				$aid=implode('|', array_keys(self::str_to_author($v)));
				$pattern='/([^;]+?)\(id=('.$aid.')\)/';
				$replace='<a href="/member/info/AId/\2">\1</a>';
				$d['Author']=str_replace(';', '、',
						preg_replace($pattern, $replace, $v));
				break;
			default:
				if (is_numeric($v))
					$d[$k]=$v;
				else
					$d[$k]=wrapper::escape($v);
			} // end of switch
		} // end of foreach
		return $d;
	}

	// 处理掉字段里的html符号
	static function escape($data)
	{
		foreach ($data as $k => $v) {
			if (!is_numeric($v)) {
				$d[$k]=wrapper::escape($v);
			}
			else
				$d[$k]=$v;
		}
		return $d;
	}

	// 查询出一篇论文的全部信息
	function detail($pid)
	{
		try {
			$result=$this->db->query('select * from paper 
					where PId=:pid limit 1', array('pid'=>$pid));
			$row=$result->fetchAll();
			return $row[0];
		}
		catch (Zend_Excetpion $e) {
			return null;
		}
	}

	// 删除一篇论文
	function del($pid)
	{
		try {
			$pid=intval($pid);
			$this->db->query('delete from paper where PId='.$pid);
			$this->db->query('delete from author_paper where PId='.$pid);
			return true;
		}
		catch (Zend_Excetpion $e) {
			return false;
		}
	}

	// 查询成员是否是论文作者
	function is_author($aid, $pid)
	{
		$result=$this->db->query('select count(AId) from author_paper
					where AId=:aid and PId=:pid',
				array('aid'=>$aid, 'pid'=>$pid));
		return $result->rowCount()>0;
	}

	// 更新论文内容，一次之更新一项内容，并返回更新后的结果，失败返回''。
	function update($param, $pid)
	{
		// 检测更新字段是否合法
		$d=$this->wr->check($param, true);
		if (!is_array($d)) {
			return '';
		}

		// 筛选出出了PId以外的另"1"个字段
		$d=$this->wr->filter($d);
		if (array_key_exists('PId', $d))
			unset ($d['PId']);

		// 修改数据
		$pid=intval($pid);
		foreach ($d as $k => $v) {
			if ($k=='Author') { // 更新论文作者表
				$this->db->query("delete from author_paper where PId=$pid");
				$author=$this->str_to_author($v);
				foreach ($author as $aid => $tmp) {
					$this->db->query('insert into author_paper(AId, PId)
							values(:aid, :pid)', 
						array('aid'=>$aid, 'pid'=>$pid));
				}
				$result=$v;
			}
			else if ($k=='Date') {
				$result=$v;
				$v=strtotime($v);
			}
			else {
				$result=wrapper::escape($v);
			}
			$this->db->query("update paper set `$k`=:val where PId=:pid",
					array('val'=>$v, 'pid'=>$pid));
		}

		return $result;
	}


};
?>
